package com.global.emc.spring.chain;

import java.lang.reflect.Method;
import java.util.Map;

import org.springframework.context.support.ApplicationObjectSupport;

import com.global.emc.core.chain.SimpleChain;
import com.global.emc.core.exception.impl.EMCException;
import com.global.emc.util.StringUtils;

public class ControllerMethodAnnotationChain extends ApplicationObjectSupport implements CallMethodChain{

	@Override
	public Map<String, Object> invoker(BeforeCallMethodContent content) throws EMCException {
		SimpleChain<BeforeCallMethodContent> beforeChain = getBeforeSimpleChain(content.getMethod());
		if(null == beforeChain)
			return null;
		
		beforeChain.invoker(content);
		return null;
	}

	@Override
	public void invoker(AfterCallMethodContent content) throws EMCException {
		SimpleChain<AfterCallMethodContent> afterChain = getAfterSimpleChain(content.getMethod());
		if(null == afterChain)
			return;
		
		afterChain.invoker(content);
	}
	
	@SuppressWarnings("unchecked")
	protected SimpleChain<BeforeCallMethodContent> getBeforeSimpleChain(Method method) throws EMCException {
		BCMChain bcmChain=method.getAnnotation(BCMChain.class);
		if(null == bcmChain)
			return null;
		
		String chainId=method.getAnnotation(BCMChain.class).ref();
		if(StringUtils.isEmpty(chainId)){
			EMCException emcException = new EMCException("chainId is null of BeforeSimpleChain");
			emcException.setArgs(new String[]{method.getName()});
			throw emcException;
		}
		
		SimpleChain<BeforeCallMethodContent> simpleChain=null;
		try {
			simpleChain = super.getApplicationContext().getBean(chainId, SimpleChain.class);
		} catch (Exception e) {
			EMCException emcException = new EMCException("BeforeSimpleChain chainId is not find in the ApplicationContext",e);
			emcException.setArgs(new String[]{method.getName(),chainId});
			throw emcException;
		} 
		return simpleChain;
	}
	
	@SuppressWarnings("unchecked")
	protected SimpleChain<AfterCallMethodContent> getAfterSimpleChain(Method method) throws EMCException {
		ACMChain acmChain = method.getAnnotation(ACMChain.class);
		if(null== acmChain)
			return null;
		
		String chainId = acmChain.ref();
		if(StringUtils.isEmpty(chainId)){
			EMCException emcException = new EMCException("chainId is null of AfterSimpleChain");
			emcException.setArgs(new String[]{method.getName()});
			throw emcException;
		}
			
		SimpleChain<AfterCallMethodContent> simpleChain=null;
		try {
			simpleChain = super.getApplicationContext().getBean(chainId, SimpleChain.class);
		} catch (Exception e) {
			EMCException emcException = new EMCException("AfterSimpleChain chainId is not find in the ApplicationContext",e);
			emcException.setArgs(new String[]{method.getName(),chainId});
			throw emcException;
		}
		return simpleChain;
	}
	

}
